
#include "HiBoost.Data.h"

using namespace hi_boost;

CGlobalHiBoostSettings hi_boost::GlobalHiBoostSettings;

// [*] CGlobalHiBoostSettings

const char* CGlobalHiBoostSettings::GetText_ImageSet(int sgnImageSet) const
{
	if (sgnImageSet==0) return "Train";
	if (sgnImageSet==1) return "Test";
	return "";
}

const char* CGlobalHiBoostSettings::GetText_PosNeg(int sgnPosNeg) const
{
	if (sgnPosNeg==1) return "Pos";
	if (sgnPosNeg!=1) return "Neg";
	return "";
}

int CGlobalHiBoostSettings::GetAmount_SrcImage(int sgnImageSet, int sgnPosNeg) const
{
	if (sgnImageSet==0 && sgnPosNeg==1) return Amount_SrcImage_Train_Pos;
	if (sgnImageSet==0 && sgnPosNeg!=1) return Amount_SrcImage_Train_Neg;
	if (sgnImageSet==1 && sgnPosNeg==1) return Amount_SrcImage_Test_Pos;
	if (sgnImageSet==1 && sgnPosNeg!=1) return Amount_SrcImage_Test_Neg;
	return 0;
}

int CGlobalHiBoostSettings::GetAmount_GT_Annotation(int sgnImageSet) const
{
	if (sgnImageSet==0) return Amount_GT_Annotation_Train;
	if (sgnImageSet==1) return Amount_GT_Annotation_Test;
	return 0;
}

int CGlobalHiBoostSettings::GetAmount_Original_Annotation(int sgnImageSet) const
{
	if (sgnImageSet==0) return Amount_Original_Annotation_Train;
	if (sgnImageSet==1) return Amount_Original_Annotation_Test;
	return 0;
}

string CGlobalHiBoostSettings::GetPN_SrcImage(int sgnImageSet, int sgnPosNeg) const
{
	if (sgnImageSet==0 && sgnPosNeg==1) return strPN_SrcImage_Train_Pos.c_str();
	if (sgnImageSet==0 && sgnPosNeg!=1) return strPN_SrcImage_Train_Neg.c_str();
	if (sgnImageSet==1 && sgnPosNeg==1) return strPN_SrcImage_Test_Pos.c_str();
	if (sgnImageSet==1 && sgnPosNeg!=1) return strPN_SrcImage_Test_Neg.c_str();
	return "";
}

string CGlobalHiBoostSettings::GetPN_Original_Annotation(int sgnImageSet) const
{
	if (sgnImageSet==0) return strPN_Original_Annotation_Train.c_str();
	if (sgnImageSet==1) return strPN_Original_Annotation_Test.c_str();
	return "";
}

string CGlobalHiBoostSettings::GetPN_GT_Annotation(int sgnImageSet) const
{
	char strTemp[10001];
	sprintf_s(strTemp, "%sAnnotation.%s\\", strPN_Base_GT_Annotation.c_str(), GetText_ImageSet(sgnImageSet));
	return strTemp;
}

string CGlobalHiBoostSettings::GetPN_GT_AnnExample(int sgnImageSet) const
{
	char strTemp[10001];
	sprintf_s(strTemp, "%sAnnExample.%s\\", strPN_Base_GT_Annotation.c_str(), GetText_ImageSet(sgnImageSet));
	return strTemp;
}

string CGlobalHiBoostSettings::GetPN_CropCT(int NodeIndex, int sgnImageSet) const
{
	char strTemp[10001];
	sprintf_s(strTemp, "%sNode.%02d.%s\\", strPN_Base_CropCT.c_str(), NodeIndex, GetText_ImageSet(sgnImageSet));
	return strTemp;
}

string CGlobalHiBoostSettings::GetPN_DrawExample(int NodeIndex, int sgnImageSet) const
{
	char strTemp[10001];
	sprintf_s(strTemp, "%sNode.%02d.%s\\", strPN_Base_DrawExample.c_str(), NodeIndex, GetText_ImageSet(sgnImageSet));
	return strTemp;
}

string CGlobalHiBoostSettings::GetPN_BoostModel(int NodeIndex) const
{
	char strTemp[10001];
	sprintf_s(strTemp, "%sNode.%02d\\", strPN_Base_BoostModel.c_str(), NodeIndex);
	return strTemp;
}

string CGlobalHiBoostSettings::GetPN_BoostDetect_SingleNode(int NodeIndex) const
{
	char strTemp[10001];
	sprintf_s(strTemp, "%sNode.%02d\\", strPN_Base_BoostDetect.c_str(), NodeIndex);
	return strTemp;
}

string CGlobalHiBoostSettings::GetPN_PerceptronDetect_SingleNode(int NodeIndex) const
{
	char strTemp[10001];
	sprintf_s(strTemp, "%sNode.%02d\\", strPN_Perceptron_DetectBase.c_str(), NodeIndex);
	return strTemp;
}

string CGlobalHiBoostSettings::GetPN_PerceptronDetect_ParseLog(int sgnImageSet, int sgnPosNeg, int ImageIndex, int LayerIndex) const
{
	char strTemp[10001];
	sprintf_s(strTemp, "%s%s.%s.%04d.%02d\\",
		strPN_Perceptron_ParseLog_Detect.c_str(), GetText_ImageSet(sgnImageSet), GetText_PosNeg(sgnPosNeg), ImageIndex, LayerIndex);
	return strTemp;
}

string CGlobalHiBoostSettings::GetPerceptronImageHashName(int sgnImageSet, int sgnPosNeg, int ImageIndex) const
{
	char strTemp[10001];
	sprintf_s(strTemp, "%s%s.%s.%04d",
		strPN_Perceptron_ImageCache.c_str(), GetText_ImageSet(sgnImageSet), GetText_PosNeg(sgnPosNeg), ImageIndex);
	return strTemp;
}

void CGlobalHiBoostSettings::MakeFN_SrcImage(char* DstPtrChar, int sgnImageSet, int sgnPosNeg, int FileIndex) const
{
	sprintf(DstPtrChar, "%s%04d.jpg", GetPN_SrcImage(sgnImageSet, sgnPosNeg).c_str(), FileIndex);
}

void CGlobalHiBoostSettings::MakeFN_INRIA_Annotation(char* DstPtrChar, int sgnImageSet, int FileIndex) const
{
	if (sgnImageSet==0)
		sprintf(DstPtrChar, "%s%04d.txt", strPN_INRIA_Annotation_Train.c_str(), FileIndex);
	else
		sprintf(DstPtrChar, "%s%04d.txt", strPN_INRIA_Annotation_Test.c_str(), FileIndex);
}

void CGlobalHiBoostSettings::MakeFN_Original_Annotation(char* DstPtrChar, int sgnImageSet, int FileIndex) const
{
	sprintf(DstPtrChar, "%s%04d.txt", GetPN_Original_Annotation(sgnImageSet).c_str(), FileIndex);
}

void CGlobalHiBoostSettings::MakeFN_Original_Ann__Image(char* DstPtrChar, int sgnImageSet, int FileIndex) const
{
	sprintf(DstPtrChar, "%s%04d.jpg", GetPN_Original_Annotation(sgnImageSet).c_str(), FileIndex);
}

void CGlobalHiBoostSettings::MakeFN_GT_Annotation(char* DstPtrChar, int sgnImageSet, int FileIndex) const
{
	sprintf(DstPtrChar, "%s%04d.txt", GetPN_GT_Annotation(sgnImageSet).c_str(), FileIndex);
}

void CGlobalHiBoostSettings::MakeFN_GT_AnnExample(char* DstPtrChar, int sgnImageSet, int FileIndex) const
{
	sprintf(DstPtrChar, "%s%04d.jpg", GetPN_GT_AnnExample(sgnImageSet).c_str(), FileIndex);
}

void CGlobalHiBoostSettings::MakeFN_CropGT(char* DstPtrChar, int NodeIndex, int sgnImageSet, int FileIndex) const
{
	sprintf(DstPtrChar, "%s%04d.jpg", GetPN_CropCT(NodeIndex, sgnImageSet).c_str(), FileIndex);
}

void CGlobalHiBoostSettings::MakeFN_ExampleList(char* DstPtrChar, int NodeIndex, int sgnImageSet) const
{
	sprintf(DstPtrChar, "%sNode.%02d.%s.txt", strPN_ExampleList.c_str(), NodeIndex, GetText_ImageSet(sgnImageSet));
}

void CGlobalHiBoostSettings::MakeFN_DrawExample(char* DstPtrChar, int NodeIndex, int sgnImageSet, int ExampleIndex) const
{
	sprintf(DstPtrChar, "%s%08d.jpg", GetPN_DrawExample(NodeIndex, sgnImageSet).c_str(), ExampleIndex);
}

void CGlobalHiBoostSettings::MakeFN_BoostModel(char* DstPtrChar, int NodeIndex) const
{
	sprintf(DstPtrChar, "%sBoostModel.txt", GetPN_BoostModel(NodeIndex).c_str());
}

void CGlobalHiBoostSettings::MakeFN_BoostTrainLog(char* DstPtrChar, int NodeIndex) const
{
	sprintf(DstPtrChar, "%sBoostTrain.log", GetPN_BoostModel(NodeIndex).c_str());
}

void CGlobalHiBoostSettings::MakeFN_BoostTestROC(char* DstPtrChar, int NodeIndex) const
{
	sprintf(DstPtrChar, "%sBoostTestROC.txt", GetPN_BoostModel(NodeIndex).c_str());
}

int CGlobalHiBoostSettings::GetBicParentFileNameSetIndex(int sgnImageSet, int sgnPosNeg, bool fIsCropGT) const
{
	return 0
		+ (fIsCropGT ? 0 : sgnPosNeg)
		+ sgnImageSet * FileSetTag_for_BicParentFileName
		+ (fIsCropGT ? 2 : 1) * FileSetTag_for_BicParentFileName * FileSetTag_for_BicParentFileName;
}

void CGlobalHiBoostSettings::GenerateList_BicParentFileNameSet(CSimpleTypeArray<CBicExampleParentFileNameSet>& DstList_BicParentFileNameSet, int NodeIndex) const
{
	char strTemp[10001];
	int sgnImageSet, sgnPosNeg, i_image, amount_image;

	int i_set = 0;
	bool fIsCropGT;
	DstList_BicParentFileNameSet.Resize(6);
	for ( sgnImageSet = 0; sgnImageSet < 2; ++sgnImageSet ) for ( sgnPosNeg = 0; sgnPosNeg < 3; ++sgnPosNeg )
	{
		CBicExampleParentFileNameSet& CurrentBicParentFileNameSet = DstList_BicParentFileNameSet.pElement[i_set++];
		fIsCropGT = (sgnPosNeg == 2);
		CurrentBicParentFileNameSet.SetIndex = GetBicParentFileNameSetIndex(sgnImageSet, sgnPosNeg, fIsCropGT);
		if (fIsCropGT)
			amount_image = GetAmount_GT_Annotation(sgnImageSet);
		else
			amount_image = GetAmount_SrcImage(sgnImageSet, sgnPosNeg);
		CurrentBicParentFileNameSet.FileNameList.Resize(amount_image);
		for ( i_image = 0; i_image < amount_image; ++i_image )
		{
			if (fIsCropGT)
				MakeFN_CropGT(strTemp, NodeIndex, sgnImageSet, i_image);
			else
				MakeFN_SrcImage(strTemp, sgnImageSet, sgnPosNeg, i_image);
			CurrentBicParentFileNameSet.FileNameList.pElement[i_image] = strTemp;
		}
	}
};

void CGlobalHiBoostSettings::MakeGroundTruthSet(CHiBoostGroundTruthList& GT_List_Train, CHiBoostGroundTruthList& GT_List_Test) const
{
	char strTemp[10001];
	int sgnImageSet;

	for ( sgnImageSet = 0; sgnImageSet < 2; ++sgnImageSet )
	{
		int i;
		CHiBoostGroundTruthList* pCurrent_GT_List;

		pCurrent_GT_List = &(sgnImageSet==0 ? GT_List_Train : GT_List_Test);
		pCurrent_GT_List->Amount_SrcImage_Pos = GetAmount_SrcImage(sgnImageSet, 1);
		pCurrent_GT_List->Amount_GroundTruth = GetAmount_GT_Annotation(sgnImageSet);
		pCurrent_GT_List->pExampleSettings = &HiBoostExampleSettings;
		pCurrent_GT_List->List_strFN_SrcImage_Pos.Clear();
		pCurrent_GT_List->List_strSrcImageHashName.Clear();
		for ( i = 0; i < pCurrent_GT_List->Amount_SrcImage_Pos; ++i )
		{
			MakeFN_SrcImage(strTemp, sgnImageSet, 1, i);
			pCurrent_GT_List->List_strFN_SrcImage_Pos.PushBack(strTemp);
			pCurrent_GT_List->List_strSrcImageHashName.PushBack(
				GetPerceptronImageHashName(sgnImageSet, 1, i));
		}
		pCurrent_GT_List->BaseImageLayerScaleList.Resize(pCurrent_GT_List->Amount_GroundTruth);
		pCurrent_GT_List->GroundTruthList.Resize(pCurrent_GT_List->Amount_GroundTruth);
		for ( i = 0; i < pCurrent_GT_List->Amount_GroundTruth; ++i )
		{
			MakeFN_GT_Annotation(strTemp, sgnImageSet, i);
			pCurrent_GT_List->GroundTruthList.pElement[i].myInit(strTemp);
			pCurrent_GT_List->BaseImageLayerScaleList.pElement[i] = HiBoostExampleSettings.ComputeGeneralIplScale(pCurrent_GT_List->GroundTruthList.pElement + i);
		}
	}
}

// [*] hi_boost::CHiBoostExampleSettings

void CHiBoostExampleSettings::myInit(string strFN_HiBoostExampleSettings, int NodeAmount)
{
	ifstream inFile(strFN_HiBoostExampleSettings.c_str());

	int i;
	int ti, tix, tiy;
	double tdx, tdy, tdw, tdh;
	CBicExampleConfig tConfig;

	tConfig.SetScanningFitBoxConfiguration(CBicExampleConfig::FIT_BOX_STYLE_MIN_SIZE, 64, 128);
	inFile>>ti>>tdx>>tdy;
	tConfig.SetPosExampleBasicConfiguration(ti, tdx, tdy);
	//inFile>>ti;
	//this->PosShakeAmount = ti;
	inFile>>tdx>>tdy>>tdw>>tdh;
	tConfig.SetPosExampleShakingConfiguration(tdx, tdy, tdw, tdh);

	this->NodeAmount = NodeAmount;
	List_PerNodeBicExampleConfig.Resize(NodeAmount); List_PerNodeBicExampleConfig.Fill(tConfig);
	List_PerNodeFeatureContextCell_W.Resize(NodeAmount); List_PerNodeFeatureContextCell_W.Fill(8.0);
	List_PerNodeFeatureContextCell_H.Resize(NodeAmount); List_PerNodeFeatureContextCell_H.Fill(8.0);

	inFile>>tix>>tiy>>tdx>>tdy; tConfig.SetStdObjectTightConfiguration(tix, tiy, tdx, tdy);
	inFile>>tix>>tiy>>tdx>>tdy; tConfig.SetStdObjectContextConfiguration(tix, tiy, tdx, tdy);
	LargeBicExampleConfig = tConfig;

	while (inFile>>ti)
	{
		if (ti<0 || ti>=NodeAmount) continue;
		i = ti;
		inFile>>tix>>tiy>>tdx>>tdy; tConfig.SetStdObjectTightConfiguration(tix, tiy, tdx, tdy);
		inFile>>tix>>tiy>>tdx>>tdy; tConfig.SetStdObjectContextConfiguration(tix, tiy, tdx, tdy);
		inFile>>tdw>>tdh;
		List_PerNodeBicExampleConfig.pElement[i] = tConfig;
		List_PerNodeFeatureContextCell_W.pElement[i] = tdw;
		List_PerNodeFeatureContextCell_H.pElement[i] = tdh;
	}

	inFile.clear();
	inFile.close();
}

CBicExampleConfig& CHiBoostExampleSettings::GetNodeBicExampleConfig(int NodeIndex)
{
	NodeIndex = (NodeIndex<0 ? 0 : (NodeIndex>=NodeAmount ? NodeAmount-1 : NodeIndex));
	return List_PerNodeBicExampleConfig.pElement[NodeIndex];
}

const CBicExampleConfig& CHiBoostExampleSettings::GetNodeBicExampleConfig(int NodeIndex) const
{
	NodeIndex = (NodeIndex<0 ? 0 : (NodeIndex>=NodeAmount ? NodeAmount-1 : NodeIndex));
	return List_PerNodeBicExampleConfig.pElement[NodeIndex];
}

void CHiBoostExampleSettings::GetNodeFeatureContextSettings(double& Context_W, double& Context_H, double& Cell_W, double& Cell_H, int NodeIndex) const
{
	NodeIndex = (NodeIndex<0 ? 0 : (NodeIndex>=NodeAmount ? NodeAmount-1 : NodeIndex));
	Context_W = List_PerNodeBicExampleConfig.pElement[NodeIndex].StdObjectContext_W;
	Context_H = List_PerNodeBicExampleConfig.pElement[NodeIndex].StdObjectContext_H;
	Cell_W = List_PerNodeFeatureContextCell_W.pElement[NodeIndex];
	Cell_H = List_PerNodeFeatureContextCell_H.pElement[NodeIndex];
}

double CHiBoostExampleSettings::ComputeGeneralIplScale(const CHiBoostNodeInstanceBoxSet* pSrcInstance) const
{
	return LargeBicExampleConfig.GetIplScaleFromTightBox(pSrcInstance->All_BoundingBox);
}

// [*] CHiBoostNodeSetAppearanceIPFE

int CHiBoostNodeSetAppearanceIPFE::s_IFB_ImageExtent;
double CHiBoostNodeSetAppearanceIPFE::s_IFB_TextonSigma;
const and_or_tree::CAbstractTree* CHiBoostNodeSetAppearanceIPFE::s_pTree;
CSimpleTypeArray<CShapePatternList> CHiBoostNodeSetAppearanceIPFE::s_SPL_List_A;
CSimpleTypeArray<CShapePatternList> CHiBoostNodeSetAppearanceIPFE::s_SPL_List_B;
CSimpleTypeArray<CShapePatternList> CHiBoostNodeSetAppearanceIPFE::s_SPL_List_C;
CSimpleTypeArray<CShapePatternList> CHiBoostNodeSetAppearanceIPFE::s_SPL_List_D;
string CHiBoostNodeSetAppearanceIPFE::s_strPN_IFB_Cache;

CHiBoostNodeSetAppearanceIPFE::CHiBoostNodeSetAppearanceIPFE()
{
	CurrentSPL_A.Clear();
	CurrentSPL_B.Clear();
	CurrentSPL_C.Clear();
	CurrentSPL_D.Clear();
	pIPFE = NULL;
	pPrototypeIFB = NULL;
	Last_nsa_NodeIndex = -1;
}

CHiBoostNodeSetAppearanceIPFE::~CHiBoostNodeSetAppearanceIPFE()
{
	CDataStructureTools::MyRelease_Single(pIPFE);
	CDataStructureTools::MyRelease_Single(pPrototypeIFB);
}

void CHiBoostNodeSetAppearanceIPFE::InitIFB_A()
{
	int i;

	CDataStructureTools::MyRelease_Single(pPrototypeIFB);
	
	pPrototypeIFB = new CImageFilterBank();
	pPrototypeIFB->myInit();

	CImageFilter_RGB* pFilter_RGB = pPrototypeIFB->pBasicFilter_RGB;

	CImageFilter_Gray* pFilter_Gray = new CImageFilter_Gray();
	pFilter_Gray->PushBackInputResponse(pFilter_RGB, 0);
	pFilter_Gray->PushBackInputResponse(pFilter_RGB, 1);
	pFilter_Gray->PushBackInputResponse(pFilter_RGB, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Gray);

	CImageFilter_Lab* pFilter_Lab = new CImageFilter_Lab();
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 0);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 1);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Lab);

	CImageFilter_Gaussian* pFilter_Gaussian = new CImageFilter_Gaussian(s_IFB_TextonSigma * 1.0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_RGB, 0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_RGB, 1);
	pFilter_Gaussian->PushBackInputResponse(pFilter_RGB, 2);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Gray, 0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 1);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Gaussian);

	CImageFilter_LoG* pFilter_LoG = new CImageFilter_LoG(s_IFB_TextonSigma * 1.0);
	pFilter_LoG->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_LoG);

	CImageFilter_1DoG* pFilter_1DoG_X = new CImageFilter_1DoG(true, s_IFB_TextonSigma * 2.0);
	pFilter_1DoG_X->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_1DoG_X);

	CImageFilter_1DoG* pFilter_1DoG_Y = new CImageFilter_1DoG(false, s_IFB_TextonSigma * 2.0);
	pFilter_1DoG_Y->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_1DoG_Y);

	CImageFilter_DooG* pFilter_DooG[6];
	for ( i = 0; i < 6; ++i )
	{
		pFilter_DooG[i] = new CImageFilter_DooG(1.0, i*PI/6, 3.0);
		pFilter_DooG[i]->PushBackInputResponse(pFilter_Lab, 0);
		pPrototypeIFB->PushBackFilter(pFilter_DooG[i]);
	}

	CImageFilter_DoG* pFilter_DoG = new CImageFilter_DoG(1.0);
	pFilter_DoG->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_DoG);

	// Setting Response Output

	pFilter_Gaussian->PushBackOutput(0);	// Gaussian(R)
	pFilter_Gaussian->PushBackOutput(1);	// Gaussian(G)
	pFilter_Gaussian->PushBackOutput(2);	// Gaussian(B)
	pFilter_Gaussian->PushBackOutput(3);	// Gaussian(Gray)
	pFilter_Gaussian->PushBackOutput(4);	// Gaussian(L)
	pFilter_Gaussian->PushBackOutput(5);	// Gaussian(a)
	pFilter_Gaussian->PushBackOutput(6);	// Gaussian(b)
	pFilter_LoG->PushBackOutput(0);			// LoG(L)
	pFilter_1DoG_X->PushBackOutput(0);		// 1DoG_X(L)
	pFilter_1DoG_Y->PushBackOutput(0);		// 1DoG_Y(L)
	for ( i = 0; i < 6; ++i )
		pFilter_DooG[i]->PushBackOutput(0);	// DooG(L, i*PI/6)
	pFilter_DoG->PushBackOutput(0);		// DoG(L)

	// Finish Filter Bank Initialization

	pPrototypeIFB->GetOutputDimension(true);

	pPrototypeIFB->SetCachePath(s_strPN_IFB_Cache);
	int AreaThreshold = (400+32) * (300+32);

	pFilter_DooG[0]->AreaThresholdForResponseCacheUsage = AreaThreshold;
	pFilter_DooG[1]->AreaThresholdForResponseCacheUsage = AreaThreshold;
	pFilter_DooG[2]->AreaThresholdForResponseCacheUsage = AreaThreshold;
	pFilter_DooG[3]->AreaThresholdForResponseCacheUsage = AreaThreshold;
	pFilter_DooG[4]->AreaThresholdForResponseCacheUsage = AreaThreshold;
	pFilter_DooG[5]->AreaThresholdForResponseCacheUsage = AreaThreshold;
	//pPrototypeIFB->EnableOutputCache(AreaThreshold, 10);
	//pPrototypeIFB->EnableOutputCache(AreaThreshold, 11);
	//pPrototypeIFB->EnableOutputCache(AreaThreshold, 12);
	//pPrototypeIFB->EnableOutputCache(AreaThreshold, 13);
	//pPrototypeIFB->EnableOutputCache(AreaThreshold, 14);
	//pPrototypeIFB->EnableOutputCache(AreaThreshold, 15);
	//pPrototypeIFB->EnableOutputCache(AreaThreshold, 16);
}

void CHiBoostNodeSetAppearanceIPFE::InitIFB_B()
{
	pPrototypeIFB = new CImageFilterBank();
	pPrototypeIFB->myInit();

	CImageFilter_RGB* pFilter_RGB = pPrototypeIFB->pBasicFilter_RGB;

	CImageFilter_Lab* pFilter_Lab = new CImageFilter_Lab();
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 0);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 1);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Lab);

	CImageFilter_Gaussian* pFilter_Gaussian = new CImageFilter_Gaussian(s_IFB_TextonSigma * 1.0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 1);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Gaussian);

	CImageFilter_LoG* pFilter_LoG = new CImageFilter_LoG(s_IFB_TextonSigma * 1.0);
	pFilter_LoG->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_LoG);

	CImageFilter_1DoG* pFilter_1DoG_X = new CImageFilter_1DoG(true, s_IFB_TextonSigma * 2.0);
	pFilter_1DoG_X->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_1DoG_X);

	CImageFilter_1DoG* pFilter_1DoG_Y = new CImageFilter_1DoG(false, s_IFB_TextonSigma * 2.0);
	pFilter_1DoG_Y->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_1DoG_Y);

	CImageFilter_Gradient* pFilter_Gradient = new CImageFilter_Gradient(s_IFB_TextonSigma * 2.0, false);
	pFilter_Gradient->PushBackInputResponse(pFilter_RGB, 0);
	pFilter_Gradient->PushBackInputResponse(pFilter_RGB, 1);
	pFilter_Gradient->PushBackInputResponse(pFilter_RGB, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Gradient);

	CImageFilter_2D_Histogram* pFilter_2D_Histogram = 
		new CImageFilter_2D_Histogram(0, 1, 9, -PI/2, +PI/2, CImageFilter_2D_Histogram::MODE_BOUNDING, true);
	pFilter_2D_Histogram->PushBackInputResponse(pFilter_Gradient, 0);
	pFilter_2D_Histogram->PushBackInputResponse(pFilter_Gradient, 1);
	pPrototypeIFB->PushBackFilter(pFilter_2D_Histogram);

	// Setting Response Output

	pFilter_Gaussian->PushBackOutput(0);	// Gaussian(L)
	pFilter_Gaussian->PushBackOutput(1);	// Gaussian(a)
	pFilter_Gaussian->PushBackOutput(2);	// Gaussian(b)
	pFilter_LoG->PushBackOutput(0);			// LoG(L)
	pFilter_1DoG_X->PushBackOutput(0);		// 1DoG_X(L)
	pFilter_1DoG_Y->PushBackOutput(0);		// 1DoG_Y(L)

	pFilter_2D_Histogram->PushBackOutput(0);
	pFilter_2D_Histogram->PushBackOutput(1);
	pFilter_2D_Histogram->PushBackOutput(2);
	pFilter_2D_Histogram->PushBackOutput(3);
	pFilter_2D_Histogram->PushBackOutput(4);
	pFilter_2D_Histogram->PushBackOutput(5);
	pFilter_2D_Histogram->PushBackOutput(6);
	pFilter_2D_Histogram->PushBackOutput(7);
	pFilter_2D_Histogram->PushBackOutput(8);

	// Finish Filter Bank Initialization

	pPrototypeIFB->GetOutputDimension(true);

	pPrototypeIFB->SetCachePath(s_strPN_IFB_Cache);
	int AreaThreshold = (400+32) * (300+32);

	//pFilter_Gradient->AreaThresholdForResponseCacheUsage = AreaThreshold;
	//pFilter_2D_Histogram->AreaThresholdForResponseCacheUsage = AreaThreshold;

	////pPrototypeIFB->EnableOutputCache(AreaThreshold, 0);
}

void CHiBoostNodeSetAppearanceIPFE::InitIFB_C()
{
	pPrototypeIFB = new CImageFilterBank();
	pPrototypeIFB->myInit();

	CImageFilter_RGB* pFilter_RGB = pPrototypeIFB->pBasicFilter_RGB;

	CImageFilter_Func_Sqrt* pFilter_Sqrt = new CImageFilter_Func_Sqrt();
	pFilter_Sqrt->PushBackInputResponse(pFilter_RGB, 0);
	pFilter_Sqrt->PushBackInputResponse(pFilter_RGB, 1);
	pFilter_Sqrt->PushBackInputResponse(pFilter_RGB, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Sqrt);

	CImageFilter_Gradient* pFilter_Gradient = new CImageFilter_Gradient(0.0, false); // s_IFB_TextonSigma * 2.0, false);
	pFilter_Gradient->PushBackInputResponse(pFilter_Sqrt, 0);
	pFilter_Gradient->PushBackInputResponse(pFilter_Sqrt, 1);
	pFilter_Gradient->PushBackInputResponse(pFilter_Sqrt, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Gradient);

	CImageFilter_2D_Histogram* pFilter_2D_Histogram = 
		new CImageFilter_2D_Histogram(0, 1, 9, -PI/2, +PI/2, CImageFilter_2D_Histogram::MODE_BOUNDING, true);
	pFilter_2D_Histogram->PushBackInputResponse(pFilter_Gradient, 0);
	pFilter_2D_Histogram->PushBackInputResponse(pFilter_Gradient, 1);
	pPrototypeIFB->PushBackFilter(pFilter_2D_Histogram);

	CImageFilter* pFO = pFilter_2D_Histogram;

	CImageFilter_Kernel2D* pFilter_AvgHist = new CImageFilter_Kernel2D();
	pFilter_AvgHist->Ker.fType = +1;
	pFilter_AvgHist->Ker.kernelX.SetLinearInterpolation(8);
	pFilter_AvgHist->Ker.kernelY.SetLinearInterpolation(8);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 0);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 1);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 2);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 3);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 4);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 5);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 6);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 7);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 8);
	pPrototypeIFB->PushBackFilter(pFilter_AvgHist);
	pFO = pFilter_AvgHist;

	// Setting Response Output

	pFO->PushBackOutput(0);
	pFO->PushBackOutput(1);
	pFO->PushBackOutput(2);
	pFO->PushBackOutput(3);
	pFO->PushBackOutput(4);
	pFO->PushBackOutput(5);
	pFO->PushBackOutput(6);
	pFO->PushBackOutput(7);
	pFO->PushBackOutput(8);

	// Finish Filter Bank Initialization

	pPrototypeIFB->GetOutputDimension(true);

	pPrototypeIFB->SetCachePath(s_strPN_IFB_Cache);
	int AreaThreshold = (400+32) * (300+32);

	//pFilter_Gradient->AreaThresholdForResponseCacheUsage = AreaThreshold;
	//pFilter_2D_Histogram->AreaThresholdForResponseCacheUsage = AreaThreshold;
}

void CHiBoostNodeSetAppearanceIPFE::InitIFB_D()
{
	pPrototypeIFB = new CImageFilterBank();
	pPrototypeIFB->myInit();

	CImageFilter_RGB* pFilter_RGB = pPrototypeIFB->pBasicFilter_RGB;

	CImageFilter_Lab* pFilter_Lab = new CImageFilter_Lab();
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 0);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 1);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Lab);

	CImageFilter_Gaussian* pFilter_Gaussian = new CImageFilter_Gaussian(s_IFB_TextonSigma * 1.0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 1);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Gaussian);

	CImageFilter_LoG* pFilter_LoG = new CImageFilter_LoG(s_IFB_TextonSigma * 1.0);
	pFilter_LoG->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_LoG);

	CImageFilter_1DoG* pFilter_1DoG_X = new CImageFilter_1DoG(true, s_IFB_TextonSigma * 2.0);
	pFilter_1DoG_X->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_1DoG_X);

	CImageFilter_1DoG* pFilter_1DoG_Y = new CImageFilter_1DoG(false, s_IFB_TextonSigma * 2.0);
	pFilter_1DoG_Y->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_1DoG_Y);

	CImageFilter_Gradient* pFilter_Gradient = new CImageFilter_Gradient(0.0, false); // s_IFB_TextonSigma * 2.0, false);
	pFilter_Gradient->PushBackInputResponse(pFilter_Gaussian, 0);
	pPrototypeIFB->PushBackFilter(pFilter_Gradient);

	CImageFilter_2D_Histogram* pFilter_2D_Histogram = 
		new CImageFilter_2D_Histogram(0, 1, 9, -PI/2, +PI/2, CImageFilter_2D_Histogram::MODE_BOUNDING, true);
	pFilter_2D_Histogram->PushBackInputResponse(pFilter_Gradient, 0);
	pFilter_2D_Histogram->PushBackInputResponse(pFilter_Gradient, 1);
	pPrototypeIFB->PushBackFilter(pFilter_2D_Histogram);

	CImageFilter_Kernel2D* pFilter_AvgHist = new CImageFilter_Kernel2D();
	pFilter_AvgHist->Ker.fType = +1;
	pFilter_AvgHist->Ker.kernelX.SetLinearInterpolation(4);
	pFilter_AvgHist->Ker.kernelY.SetLinearInterpolation(4);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 0);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 1);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 2);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 3);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 4);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 5);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 6);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 7);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 8);
	pPrototypeIFB->PushBackFilter(pFilter_AvgHist);

	// Setting Response Output

	pFilter_Gaussian->PushBackOutput(0);	// Gaussian(L)
	pFilter_Gaussian->PushBackOutput(1);	// Gaussian(a)
	pFilter_Gaussian->PushBackOutput(2);	// Gaussian(b)
	pFilter_LoG->PushBackOutput(0);			// LoG(L)
	pFilter_1DoG_X->PushBackOutput(0);		// 1DoG_X(L)
	pFilter_1DoG_Y->PushBackOutput(0);		// 1DoG_Y(L)

	pFilter_AvgHist->PushBackOutput(0);		// Gradient Histogram
	pFilter_AvgHist->PushBackOutput(1);
	pFilter_AvgHist->PushBackOutput(2);
	pFilter_AvgHist->PushBackOutput(3);
	pFilter_AvgHist->PushBackOutput(4);
	pFilter_AvgHist->PushBackOutput(5);
	pFilter_AvgHist->PushBackOutput(6);
	pFilter_AvgHist->PushBackOutput(7);
	pFilter_AvgHist->PushBackOutput(8);

	// Finish Filter Bank Initialization

	pPrototypeIFB->GetOutputDimension(true);

	pPrototypeIFB->SetCachePath(s_strPN_IFB_Cache);
	int AreaThreshold = (400+32) * (300+32);

	//pFilter_Gradient->AreaThresholdForResponseCacheUsage = AreaThreshold;
	//pFilter_2D_Histogram->AreaThresholdForResponseCacheUsage = AreaThreshold;
}

void CHiBoostNodeSetAppearanceIPFE::InitIPFE_A()
{
	CDataStructureTools::MyRelease_Single(pIPFE);

	int i, ii;
	ii = pPrototypeIFB->GetOutputDimension();
	C_IPFC_ImageFilterBankOwner* pIFBO = new C_IPFC_ImageFilterBankOwner(pPrototypeIFB->myClone(), s_IFB_ImageExtent, false);
	for ( i = 0; i < ii; ++i )
		pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_MeanAndVairance(&CurrentSPL_C), &i);

	CCompositeIPFC* pCompositeIPFC = new CCompositeIPFC();
	pCompositeIPFC->PushBack(pIFBO);

	pIPFE = new CBasicIPFE(pCompositeIPFC);
}

void CHiBoostNodeSetAppearanceIPFE::InitIPFE_B()
{
	CDataStructureTools::MyRelease_Single(pIPFE);

	int i, ii;
	ii = pPrototypeIFB->GetOutputDimension();
	C_IPFC_ImageFilterBankOwner* pIFBO = new C_IPFC_ImageFilterBankOwner(pPrototypeIFB->myClone(), s_IFB_ImageExtent, false);

	CSimpleTypeArray<int> NI;
	NI.Clear(); for ( i = 0; i < ii; ++i ) NI.PushBack(i);

	CMyNormalizer_L2_NORM* pNormalizer = new CMyNormalizer_L2_NORM(1.0);
	C_IPFC_ResponseUser_BlockNormalizer* pBlockNormalizer = new C_IPFC_ResponseUser_BlockNormalizer(ii, &CurrentSPL_C, true, pNormalizer, false);

	pIFBO->PushBackResponseUser(pBlockNormalizer, NI.pElement);

	CCompositeIPFC* pCompositeIPFC = new CCompositeIPFC();
	pCompositeIPFC->PushBack(pIFBO);

	pIPFE = new CBasicIPFE(pCompositeIPFC);
}

void CHiBoostNodeSetAppearanceIPFE::InitIPFE_C()
{
	CDataStructureTools::MyRelease_Single(pIPFE);
	CSimpleTypeArray<int> NI;

	int i, ii;
	ii = pPrototypeIFB->GetOutputDimension();
	C_IPFC_ImageFilterBankOwner* pIFBO = new C_IPFC_ImageFilterBankOwner(pPrototypeIFB->myClone(), s_IFB_ImageExtent, false);

	for ( i = 0; i < 6; ++i )
		pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_MeanAndVairance(&CurrentSPL_B), &i);

	CMyNormalizer_L2_NORM* pNormalizer = new CMyNormalizer_L2_NORM(1.0);

	NI.Clear(); for ( i = 0; i < 1; ++i ) NI.PushBack(i);
	C_IPFC_ResponseUser_BlockNormalizer* pBlockNormalizer_L = new C_IPFC_ResponseUser_BlockNormalizer((int)NI.Size, &CurrentSPL_A, true, pNormalizer->myClone(), false);
	pIFBO->PushBackResponseUser(pBlockNormalizer_L, NI.pElement);

	NI.Clear(); for ( i = 1; i < 2; ++i ) NI.PushBack(i);
	C_IPFC_ResponseUser_BlockNormalizer* pBlockNormalizer_a = new C_IPFC_ResponseUser_BlockNormalizer((int)NI.Size, &CurrentSPL_A, true, pNormalizer->myClone(), false);
	pIFBO->PushBackResponseUser(pBlockNormalizer_a, NI.pElement);

	NI.Clear(); for ( i = 2; i < 3; ++i ) NI.PushBack(i);
	C_IPFC_ResponseUser_BlockNormalizer* pBlockNormalizer_b = new C_IPFC_ResponseUser_BlockNormalizer((int)NI.Size, &CurrentSPL_A, true, pNormalizer->myClone(), false);
	pIFBO->PushBackResponseUser(pBlockNormalizer_b, NI.pElement);

	NI.Clear(); for ( i = 6; i < 15; ++i ) NI.PushBack(i);
	C_IPFC_ResponseUser_BlockNormalizer* pBlockNormalizer_HOG = new C_IPFC_ResponseUser_BlockNormalizer((int)NI.Size, &CurrentSPL_A, true, pNormalizer->myClone(), false);
	pIFBO->PushBackResponseUser(pBlockNormalizer_HOG, NI.pElement);

	CCompositeIPFC* pCompositeIPFC = new CCompositeIPFC();
	pCompositeIPFC->PushBack(pIFBO);

	pIPFE = new CBasicIPFE(pCompositeIPFC);

	CDataStructureTools::MyRelease_Single(pNormalizer);
}

void CHiBoostNodeSetAppearanceIPFE::InitIPFE_D()
{
	// Filter Bank Start

	pPrototypeIFB = new CImageFilterBank();
	pPrototypeIFB->myInit();

	CImageFilter_RGB* pFilter_RGB = pPrototypeIFB->pBasicFilter_RGB;

	CImageFilter_Lab* pFilter_Lab = new CImageFilter_Lab();
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 0);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 1);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Lab);

	CImageFilter_Gaussian* pFilter_Gaussian = new CImageFilter_Gaussian(s_IFB_TextonSigma * 1.0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 1);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Gaussian);

	CImageFilter_LoG* pFilter_LoG = new CImageFilter_LoG(s_IFB_TextonSigma * 1.0);
	pFilter_LoG->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_LoG);

	CImageFilter_1DoG* pFilter_1DoG_X = new CImageFilter_1DoG(true, s_IFB_TextonSigma * 2.0);
	pFilter_1DoG_X->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_1DoG_X);

	CImageFilter_1DoG* pFilter_1DoG_Y = new CImageFilter_1DoG(false, s_IFB_TextonSigma * 2.0);
	pFilter_1DoG_Y->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_1DoG_Y);

	// Setting Response Output

	pFilter_Gaussian->PushBackOutput(0);	// Gaussian(L)
	pFilter_Gaussian->PushBackOutput(1);	// Gaussian(a)
	pFilter_Gaussian->PushBackOutput(2);	// Gaussian(b)
	pFilter_LoG->PushBackOutput(0);			// LoG(L)
	pFilter_1DoG_X->PushBackOutput(0);		// 1DoG_X(L)
	pFilter_1DoG_Y->PushBackOutput(0);		// 1DoG_Y(L)

	// Finish Filter Bank Initialization

	pPrototypeIFB->GetOutputDimension(true);

	pPrototypeIFB->SetCachePath(s_strPN_IFB_Cache);
	int AreaThreshold = (400+32) * (300+32);

	// TODO: Make Cache Settings Here

	// Filter Bank Finished
	
	// IPFE Start

	CDataStructureTools::MyRelease_Single(pIPFE);
	CSimpleTypeArray<int> NI;
	int i, ii, iStart, iAmount;

	ii = pPrototypeIFB->GetOutputDimension();
	C_IPFC_ImageFilterBankOwner* pIFBO = new C_IPFC_ImageFilterBankOwner(pPrototypeIFB->myClone(), s_IFB_ImageExtent, false);

	iStart = 0; iAmount = 6; for ( i = iStart; i < iStart + iAmount; ++i )
		pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_Mean_and_Variance(
			C_IPFC_ResponseUser_Mean_and_Variance::MODE_MEAN_IN_CELL | C_IPFC_ResponseUser_Mean_and_Variance::MODE_VARIANCE_IN_CELL
			,&CurrentSPL_C), &i);

	iStart = 0; iAmount = 6; for ( i = iStart; i < iStart + iAmount; ++i )
		pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_Mean_and_Variance(
			C_IPFC_ResponseUser_Mean_and_Variance::MODE_MEAN_OVER_BLOCK
			,&CurrentSPL_D), &i);

	CCompositeIPFC* pCompositeIPFC = new CCompositeIPFC();
	pCompositeIPFC->PushBack(pIFBO);

	pIPFE = new CBasicIPFE(pCompositeIPFC);

	// IPFE Finished
}

void CHiBoostNodeSetAppearanceIPFE::InitIPFE_E()
{
	// Filter Bank Start

	pPrototypeIFB = new CImageFilterBank();
	pPrototypeIFB->myInit();

	CImageFilter_RGB* pFilter_RGB = pPrototypeIFB->pBasicFilter_RGB;

	CImageFilter_Lab* pFilter_Lab = new CImageFilter_Lab();
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 0);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 1);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Lab);

	CImageFilter_Gaussian* pFilter_Gaussian = new CImageFilter_Gaussian(s_IFB_TextonSigma * 1.0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 1);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Gaussian);

	CImageFilter_LoG* pFilter_LoG = new CImageFilter_LoG(s_IFB_TextonSigma * 1.0);
	pFilter_LoG->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_LoG);

	CImageFilter_1DoG* pFilter_1DoG_X = new CImageFilter_1DoG(true, s_IFB_TextonSigma * 2.0);
	pFilter_1DoG_X->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_1DoG_X);

	CImageFilter_1DoG* pFilter_1DoG_Y = new CImageFilter_1DoG(false, s_IFB_TextonSigma * 2.0);
	pFilter_1DoG_Y->PushBackInputResponse(pFilter_Lab, 0);
	pPrototypeIFB->PushBackFilter(pFilter_1DoG_Y);

	CImageFilter_Gradient* pFilter_Gradient = new CImageFilter_Gradient(0.0, false); // s_IFB_TextonSigma * 2.0, false);
	pFilter_Gradient->PushBackInputResponse(pFilter_Gaussian, 0);
	pPrototypeIFB->PushBackFilter(pFilter_Gradient);

	CImageFilter_2D_Histogram* pFilter_2D_Histogram = 
		new CImageFilter_2D_Histogram(0, 1, 9, -PI/2, +PI/2, CImageFilter_2D_Histogram::MODE_BOUNDING, true);
	pFilter_2D_Histogram->PushBackInputResponse(pFilter_Gradient, 0);
	pFilter_2D_Histogram->PushBackInputResponse(pFilter_Gradient, 1);
	pPrototypeIFB->PushBackFilter(pFilter_2D_Histogram);

	CImageFilter_Kernel2D* pFilter_AvgHist = new CImageFilter_Kernel2D();
	pFilter_AvgHist->Ker.fType = +1;
	pFilter_AvgHist->Ker.kernelX.SetLinearInterpolation(4);
	pFilter_AvgHist->Ker.kernelY.SetLinearInterpolation(4);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 0);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 1);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 2);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 3);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 4);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 5);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 6);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 7);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 8);
	pPrototypeIFB->PushBackFilter(pFilter_AvgHist);

	// Setting Response Output

	pFilter_Gaussian->PushBackOutput(0);	// Gaussian(L)
	pFilter_Gaussian->PushBackOutput(1);	// Gaussian(a)
	pFilter_Gaussian->PushBackOutput(2);	// Gaussian(b)
	pFilter_LoG->PushBackOutput(0);			// LoG(L)
	pFilter_1DoG_X->PushBackOutput(0);		// 1DoG_X(L)
	pFilter_1DoG_Y->PushBackOutput(0);		// 1DoG_Y(L)

	pFilter_AvgHist->PushBackOutput(0);		// Gradient Histogram
	pFilter_AvgHist->PushBackOutput(1);
	pFilter_AvgHist->PushBackOutput(2);
	pFilter_AvgHist->PushBackOutput(3);
	pFilter_AvgHist->PushBackOutput(4);
	pFilter_AvgHist->PushBackOutput(5);
	pFilter_AvgHist->PushBackOutput(6);
	pFilter_AvgHist->PushBackOutput(7);
	pFilter_AvgHist->PushBackOutput(8);

	// Finish Filter Bank Initialization

	pPrototypeIFB->GetOutputDimension(true);

	pPrototypeIFB->SetCachePath(s_strPN_IFB_Cache);
	int AreaThreshold = (400+32) * (300+32);

	// TODO: Make Cache Settings Here

	// Filter Bank Finished

	// IPFE Start

	CDataStructureTools::MyRelease_Single(pIPFE);
	CSimpleTypeArray<int> NI;
	int i, ii, iStart, iAmount;

	ii = pPrototypeIFB->GetOutputDimension();
	C_IPFC_ImageFilterBankOwner* pIFBO = new C_IPFC_ImageFilterBankOwner(pPrototypeIFB->myClone(), s_IFB_ImageExtent, false);

	iStart = 0; iAmount = 15; for ( i = iStart; i < iStart + iAmount; ++i )
	if (i != 3)
		pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_Mean_and_Variance(
		C_IPFC_ResponseUser_Mean_and_Variance::MODE_MEAN_IN_CELL | C_IPFC_ResponseUser_Mean_and_Variance::MODE_VARIANCE_IN_CELL,
		&CurrentSPL_A), &i);

	iStart = 0; iAmount = 15; for ( i = iStart; i < iStart + iAmount; ++i )
	if (i != 3)
		pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_Mean_and_Variance(
		C_IPFC_ResponseUser_Mean_and_Variance::MODE_MEAN_IN_CELL |
		//C_IPFC_ResponseUser_Mean_and_Variance::MODE_MEAN_OVER_BLOCK |
		C_IPFC_ResponseUser_Mean_and_Variance::MODE_VARIANCE_IN_CELL |
		C_IPFC_ResponseUser_Mean_and_Variance::MODE_VARIANCE_OVER_BLOCK,
		&CurrentSPL_B), &i);

	//iStart = 0; iAmount = 1; NI.Clear(); for ( i = iStart; i < iStart + iAmount; ++i ) NI.PushBack(i);
	//pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_BlockNormalizer(iAmount, &CurrentSPL_C, new CMyNormalizer_L2_NORM(1.0), false), NI.pElement);
	//iStart = 1; iAmount = 1; NI.Clear(); for ( i = iStart; i < iStart + iAmount; ++i ) NI.PushBack(i);
	//pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_BlockNormalizer(iAmount, &CurrentSPL_C, new CMyNormalizer_L2_NORM(1.0), false), NI.pElement);
	//iStart = 2; iAmount = 1; NI.Clear(); for ( i = iStart; i < iStart + iAmount; ++i ) NI.PushBack(i);
	//pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_BlockNormalizer(iAmount, &CurrentSPL_C, new CMyNormalizer_L2_NORM(1.0), false), NI.pElement);
	////iStart = 3; iAmount = 1; NI.Clear(); for ( i = iStart; i < iStart + iAmount; ++i ) NI.PushBack(i);
	////pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_BlockNormalizer(iAmount, &CurrentSPL_C, new CMyNormalizer_L2_NORM(1.0), false), NI.pElement);
	////iStart = 4; iAmount = 1; NI.Clear(); for ( i = iStart; i < iStart + iAmount; ++i ) NI.PushBack(i);
	////pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_BlockNormalizer(iAmount, &CurrentSPL_C, new CMyNormalizer_L2_NORM(1.0), false), NI.pElement);
	////iStart = 5; iAmount = 1; NI.Clear(); for ( i = iStart; i < iStart + iAmount; ++i ) NI.PushBack(i);
	////pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_BlockNormalizer(iAmount, &CurrentSPL_C, new CMyNormalizer_L2_NORM(1.0), false), NI.pElement);

	//iStart = 6; iAmount = 9; NI.Clear(); for ( i = iStart; i < iStart + iAmount; ++i ) NI.PushBack(i);
	//pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_BlockNormalizer(iAmount, &CurrentSPL_C, new CMyNormalizer_L2_NORM(1.0), false), NI.pElement);

	CCompositeIPFC* pCompositeIPFC = new CCompositeIPFC();
	pCompositeIPFC->PushBack(pIFBO);

	pIPFE = new CBasicIPFE(pCompositeIPFC);

	// IPFE Finished
}

void CHiBoostNodeSetAppearanceIPFE::InitIPFE_F()
{
	// Filter Bank Start

	pPrototypeIFB = new CImageFilterBank();
	pPrototypeIFB->myInit();

	CImageFilter_RGB* pFilter_RGB = pPrototypeIFB->pBasicFilter_RGB;

	CImageFilter_Lab* pFilter_Lab = new CImageFilter_Lab();
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 0);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 1);
	pFilter_Lab->PushBackInputResponse(pFilter_RGB, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Lab);

	CImageFilter_Gaussian* pFilter_Gaussian = new CImageFilter_Gaussian(s_IFB_TextonSigma * 1.0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_RGB, 0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_RGB, 1);
	pFilter_Gaussian->PushBackInputResponse(pFilter_RGB, 2);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 0);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 1);
	pFilter_Gaussian->PushBackInputResponse(pFilter_Lab, 2);
	pPrototypeIFB->PushBackFilter(pFilter_Gaussian);

	CImageFilter_Gradient* pFilter_Gradient = new CImageFilter_Gradient(0.0, false);
	pFilter_Gradient->PushBackInputResponse(pFilter_Gaussian, 3);
	pPrototypeIFB->PushBackFilter(pFilter_Gradient);

	CImageFilter_2D_Histogram* pFilter_2D_Histogram = 
		new CImageFilter_2D_Histogram(0, 1, 9, -PI/2, +PI/2, CImageFilter_2D_Histogram::MODE_BOUNDING, true);
	pFilter_2D_Histogram->PushBackInputResponse(pFilter_Gradient, 0);
	pFilter_2D_Histogram->PushBackInputResponse(pFilter_Gradient, 1);
	pPrototypeIFB->PushBackFilter(pFilter_2D_Histogram);

	CImageFilter_Kernel2D* pFilter_AvgHist = new CImageFilter_Kernel2D();
	pFilter_AvgHist->Ker.fType = +1;
	pFilter_AvgHist->Ker.kernelX.SetLinearInterpolation(4);
	pFilter_AvgHist->Ker.kernelY.SetLinearInterpolation(4);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 0);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 1);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 2);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 3);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 4);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 5);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 6);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 7);
	pFilter_AvgHist->PushBackInputResponse(pFilter_2D_Histogram, 8);
	pPrototypeIFB->PushBackFilter(pFilter_AvgHist);

	// Setting Response Output

	pFilter_Gaussian->PushBackOutput(0);	// Gaussian(L)
	pFilter_Gaussian->PushBackOutput(1);	// Gaussian(a)
	pFilter_Gaussian->PushBackOutput(2);	// Gaussian(b)
	pFilter_Gaussian->PushBackOutput(3);	// Gaussian(L)
	pFilter_Gaussian->PushBackOutput(4);	// Gaussian(a)
	pFilter_Gaussian->PushBackOutput(5);	// Gaussian(b)

	pFilter_AvgHist->PushBackOutput(0);		// Gradient Histogram
	pFilter_AvgHist->PushBackOutput(1);
	pFilter_AvgHist->PushBackOutput(2);
	pFilter_AvgHist->PushBackOutput(3);
	pFilter_AvgHist->PushBackOutput(4);
	pFilter_AvgHist->PushBackOutput(5);
	pFilter_AvgHist->PushBackOutput(6);
	pFilter_AvgHist->PushBackOutput(7);
	pFilter_AvgHist->PushBackOutput(8);

	// Finish Filter Bank Initialization

	pPrototypeIFB->GetOutputDimension(true);

	pPrototypeIFB->SetCachePath(s_strPN_IFB_Cache);
	int AreaThreshold = (400+32) * (300+32);

	// TODO: Make Cache Settings Here

	// Filter Bank Finished

	// IPFE Start

	CDataStructureTools::MyRelease_Single(pIPFE);
	CSimpleTypeArray<int> NI;
	int i, ii, iStart, iAmount;

	ii = pPrototypeIFB->GetOutputDimension();
	C_IPFC_ImageFilterBankOwner* pIFBO = new C_IPFC_ImageFilterBankOwner(pPrototypeIFB->myClone(), s_IFB_ImageExtent, false);

	//iStart = 0; iAmount = 1; for ( i = iStart; i < iStart + iAmount; ++i )
	iStart = 0; iAmount = 6; for ( i = iStart; i < iStart + iAmount; ++i )
		pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_Mean_and_Variance(
		C_IPFC_ResponseUser_Mean_and_Variance::MODE_MEAN_IN_CELL | C_IPFC_ResponseUser_Mean_and_Variance::MODE_VARIANCE_IN_CELL,
		&CurrentSPL_A), &i);

	//iStart = 0; iAmount = 1; for ( i = iStart; i < iStart + iAmount; ++i )
	iStart = 0; iAmount = 6; for ( i = iStart; i < iStart + iAmount; ++i )
		pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_Mean_and_Variance(
		C_IPFC_ResponseUser_Mean_and_Variance::MODE_MEAN_IN_CELL |
		//C_IPFC_ResponseUser_Mean_and_Variance::MODE_MEAN_OVER_BLOCK |
		C_IPFC_ResponseUser_Mean_and_Variance::MODE_VARIANCE_IN_CELL |
		C_IPFC_ResponseUser_Mean_and_Variance::MODE_VARIANCE_OVER_BLOCK,
		&CurrentSPL_B), &i);

	//iStart = 6; iAmount = 1; NI.Clear(); for ( i = iStart; i < iStart + iAmount; ++i ) NI.PushBack(i);
	iStart = 6; iAmount = 9; NI.Clear(); for ( i = iStart; i < iStart + iAmount; ++i ) NI.PushBack(i);
	pIFBO->PushBackResponseUser(new C_IPFC_ResponseUser_BlockNormalizer(iAmount, &CurrentSPL_C, true, new CMyNormalizer_L2_NORM(1.0), false), NI.pElement);

	CCompositeIPFC* pCompositeIPFC = new CCompositeIPFC();
	pCompositeIPFC->PushBack(pIFBO);

	pIPFE = new CBasicIPFE(pCompositeIPFC);

	// IPFE Finished
}

CImagePositionFeatureExtractor* CHiBoostNodeSetAppearanceIPFE::GetNodeAppearnceIPFE(int NodeIndex)
{
	if (pIPFE == NULL)
	{
		//InitIFB_A();
		//InitIPFE_A();
	
		//InitIFB_B();
		//InitIPFE_A();

		//InitIFB_C();
		//InitIPFE_B();

		//InitIFB_D();
		//InitIPFE_C();

		//InitIPFE_D();

		//InitIPFE_E();

		InitIPFE_F();
	}

	if (NodeIndex<0 || NodeIndex>=s_pTree->NodeAmount || NodeIndex>=s_pTree->NodeAmount)
	{
		CurrentSPL_A.Clear();
		CurrentSPL_B.Clear();
		CurrentSPL_C.Clear();
		CurrentSPL_D.Clear();
		Last_nsa_NodeIndex = -1;
	}
	else
	{
		CurrentSPL_A = s_SPL_List_A.pElement[NodeIndex];
		CurrentSPL_B = s_SPL_List_B.pElement[NodeIndex];
		CurrentSPL_C = s_SPL_List_C.pElement[NodeIndex];
		CurrentSPL_D = s_SPL_List_D.pElement[NodeIndex];
		Last_nsa_NodeIndex = NodeIndex;
	}
	pIPFE->RecomputeFeatureDimension();
	return pIPFE;
}

//// [*] CHiBoostExample
//
//bool CHiBoostExample::InputFromStream(istream& inStream)
//{
//	if (!(inStream>>fIsExamplePos>>fIsImagePos>>FileIndex>>real_x>>real_y>>layer_scale_x>>layer_scale_y))
//		return false;
//	return true;
//}
//
//void CHiBoostExample::OutputToStream(ostream& outStream) const
//{
//	outStream<<'\t'<<fIsExamplePos;
//	outStream<<'\t'<<fIsImagePos;
//	outStream<<'\t'<<FileIndex;
//	outStream.precision(3);
//	outStream<<'\t'<<fixed<<real_x;
//	outStream<<'\t'<<fixed<<real_y;
//	outStream.precision(8);
//	outStream<<'\t'<<fixed<<layer_scale_x;
//	outStream<<'\t'<<fixed<<layer_scale_y;
//	outStream<<endl;
//}
//
//// [*] CHiBoostExampleConfig
//
//CHiBoostExampleConfig::CHiBoostExampleConfig()
//{
//	pTree = NULL;
//	pHiBoostNodeContextConfig = NULL;
//	strPN_Base_CropGT = "";
//	__fPartSizesInitialized = false;
//
//	ExampleAmount = 0;
//}
//
//void CHiBoostExampleConfig::myInit(
//	and_or_tree::CAbstractTree* pFixedTree, CHiBoostNodeContextConfig* pFixedHiBoostNodeContextConfig,
//	int ObjectExtent, int PartExtent,
//	int StdObjectBoundingBox_W, int StdObjectBoundingBox_H,
//	double CropGT_xInferenceScale, double CropGT_yInferenceScale,
//	string strPN_Base_CropGT)
//{
//	this->pTree = pFixedTree;
//	this->pHiBoostNodeContextConfig = pFixedHiBoostNodeContextConfig;
//	this->strPN_Base_CropGT = strPN_Base_CropGT;
//
//	this->ObjectExtent = ObjectExtent;
//	this->PartExtent = PartExtent;
//	this->StdObjectBoundingBox_W = StdObjectBoundingBox_W;
//	this->StdObjectBoundingBox_H = StdObjectBoundingBox_H;
//	this->CropGT_xInferenceScale = CropGT_xInferenceScale;
//	this->CropGT_yInferenceScale = CropGT_yInferenceScale;
//
//	ExampleAmount = pTree->ExampleAmount;
//
//	__fPartSizesInitialized = false;
//
//	LoadPartCenterOffset();
//}
//
//void CHiBoostExampleConfig::MakeFN_PartCenterOffset(char* DstPtrChar) const
//{
//	sprintf(DstPtrChar, "%sPartCenterOffset.txt", strPN_Base_CropGT.c_str());
//}
//
//void CHiBoostExampleConfig::SavePartCenterOffset() const
//{
//	char strTemp[10001];
//	MakeFN_PartCenterOffset(strTemp);
//	ofstream outFile(strTemp);
//
//	int i;
//	for ( i = 0; i < ExampleAmount; ++i )
//	{
//		outFile.precision(9);
//		outFile<<"\t"<<setw(12)<<fixed<<PartCenterOffset_mx.pElement[i];
//		outFile<<"\t"<<setw(12)<<fixed<<PartCenterOffset_vx.pElement[i];
//		outFile<<"\t"<<setw(12)<<fixed<<PartCenterOffset_my.pElement[i];
//		outFile<<"\t"<<setw(12)<<fixed<<PartCenterOffset_vy.pElement[i];
//		outFile<<endl;
//	}
//	outFile.clear();
//	outFile.close();
//}
//
//bool CHiBoostExampleConfig::LoadPartCenterOffset()
//{
//	char strTemp[10001];
//	MakeFN_PartCenterOffset(strTemp);
//	ifstream inFile(strTemp);
//
//	PartCenterOffset_mx.Resize(pTree->ExampleAmount); PartCenterOffset_mx.Fill(0.0);
//	PartCenterOffset_vx.Resize(pTree->ExampleAmount); PartCenterOffset_vx.Fill(0.0);
//	PartCenterOffset_my.Resize(pTree->ExampleAmount); PartCenterOffset_my.Fill(0.0);
//	PartCenterOffset_vy.Resize(pTree->ExampleAmount); PartCenterOffset_vy.Fill(0.0);
//	int i;
//	for ( i = 0; i < ExampleAmount; ++i )
//	{
//		if (!(inFile>>PartCenterOffset_mx.pElement[i])) break;
//		if (!(inFile>>PartCenterOffset_vx.pElement[i])) break;
//		if (!(inFile>>PartCenterOffset_my.pElement[i])) break;
//		if (!(inFile>>PartCenterOffset_vy.pElement[i])) break;
//	}
//	inFile.clear();
//	inFile.close();
//	if (i < pTree->ExampleAmount)
//		return false;
//	else
//		return true;
//}
//
//void CHiBoostExampleConfig::GetCenterByPart(
//	double& DstMX, double& DstMY, double& DstVX, double& DstVY,
//	double real_x, double real_y, double image_pyramid_layer_scale,
//	int NodeIndex) const
//{
//	if (NodeIndex<0 || NodeIndex>=ExampleAmount) return;
//	DstMX = PartCenterOffset_mx.pElement[NodeIndex] / image_pyramid_layer_scale + real_x;
//	DstVX = PartCenterOffset_vx.pElement[NodeIndex] / image_pyramid_layer_scale;
//	DstMY = PartCenterOffset_my.pElement[NodeIndex] / image_pyramid_layer_scale + real_y;
//	DstVY = PartCenterOffset_vy.pElement[NodeIndex] / image_pyramid_layer_scale;
//}
//
////void CHiBoostExampleConfig::GetCenterByPart(
////	double& DstMX, double& DstMY, double& DstVX, double& DstVY,
////	double real_x, double real_y, double layer_scale_x, double layer_scale_y,
////	int NodeIndex) const
////{
////	if (NodeIndex<0 || NodeIndex>=ExampleAmount) return;
////	int std_w, std_h;
////	GetStdPartContextSize(std_w, std_h, NodeIndex);
////	double real_w, real_h;
////	real_w = std_w / layer_scale_x;
////	real_h = std_h / layer_scale_y;
////	DstMX = PartCenterOffset_mx.pElement[NodeIndex] * real_w + real_x;
////	DstVX = PartCenterOffset_vx.pElement[NodeIndex] * real_w;
////	DstMY = PartCenterOffset_my.pElement[NodeIndex] * real_h + real_y;
////	DstVY = PartCenterOffset_vy.pElement[NodeIndex] * real_h;
////}
//
//void CHiBoostExampleConfig::GetStdPartContextSize(int& DstWidth, int& DstHeight, int NodeIndex) const
//{
//	if (NodeIndex<0 || NodeIndex>=ExampleAmount)
//	{
//		DstWidth = 0;
//		DstHeight = 0;
//	}
//	else
//	{
//		const CHiBoostNodeContextConfig::CNode& tc = pHiBoostNodeContextConfig->GetDataForNode(NodeIndex);
//		DstWidth = tc.Context_W;
//		DstHeight = tc.Context_H;
//	}
//}
//
//void CHiBoostExampleConfig::AdjustImageLayerScale(double& xScale, double& yScale, int NodeIndex)
//{
//	double oxs = xScale;
//	double oys = yScale;
//
//	if (0)
//		;
//	else if (0
//		|| (NodeIndex == 1)
//		|| (NodeIndex == 2)
//		|| (NodeIndex == 3)
//		|| (NodeIndex == 4)
//		|| (NodeIndex == 5)
//		|| (NodeIndex == 9)
//		|| (NodeIndex == 10)
//		|| (NodeIndex == 13)
//		|| (NodeIndex == 14)
//		)
//	{
//		xScale = yScale = pow(oxs * oys * oys, 1.0 / 3);
//	}
//	else if (0
//		|| (NodeIndex == 6)
//		|| (NodeIndex == 7)
//		|| (NodeIndex == 11)
//		|| (NodeIndex == 12)
//		|| (NodeIndex == 15)
//		|| (NodeIndex == 16)
//		|| (NodeIndex == 17)
//		|| (NodeIndex == 18)
//		|| (NodeIndex == 19)
//		|| (NodeIndex == 20)
//		|| (NodeIndex == 21)
//		|| (NodeIndex == 25)
//		|| (NodeIndex > 25)
//		)
//	{
//		xScale = yScale = pow(oxs * oys, 1.0 / 2);
//	}
//	else if (0
//		|| (NodeIndex == 8)
//		|| (NodeIndex == 22)
//		|| (NodeIndex == 23)
//		|| (NodeIndex == 24)
//		)
//	{
//		xScale = yScale = pow(oxs * oxs * oys, 1.0 / 3);
//	}
//	else if (0
//		)
//	{
//		yScale = xScale;
//	}
//	else if (0
//		|| (NodeIndex < 0)
//		|| (1)
//		)
//	{
//		xScale = yScale;
//	}
//	else
//		;
//}
//
//void CHiBoostExampleConfig::ComputeParsedObject_ImageLayerScale(double& DstScale, const CHiBoostNodeInstanceBoxSet* pSrcParsedInstance) const
//{
//	double xScale = 1.0 * this->StdObjectBoundingBox_W / pSrcParsedInstance->All_BoundingBox.w;
//	double yScale = 1.0 * this->StdObjectBoundingBox_H / pSrcParsedInstance->All_BoundingBox.h;
//	AdjustImageLayerScale(xScale, yScale, -1);
//	DstScale = sqrt(xScale * yScale);
//}
//
//void CHiBoostExampleConfig::BuildGroundTruthExample(CHiBoostExample& DstExample, int NodeIndex, int FileIndex)
//{
//	DstExample.fIsExamplePos = true;
//	DstExample.fIsImagePos = true;
//	int cw, ch;
//	GetStdPartContextSize(cw, ch, NodeIndex);
//	DstExample.real_x = CropGT_xInferenceScale * (cw * 0.5 + PartExtent);
//	DstExample.real_y = CropGT_yInferenceScale * (ch * 0.5 + PartExtent);
//	DstExample.layer_scale_x = 1.0 / CropGT_xInferenceScale;
//	DstExample.layer_scale_y = 1.0 / CropGT_yInferenceScale;
//	DstExample.FileIndex = FileIndex;
//}
//
//int CHiBoostExampleConfig::AppendNegExamples(
//	CSimpleTypeArray<CHiBoostExample>& DstExampleList,
//	int PixelMargin, double PixelSampleRate,
//	int Image_W, int Image_H, int ScaleLevel, double ScaleFactor,
//	int NodeIndex, bool fAcceptBigImage,
//	int FileIndex, bool fIsImagePos)
//{
//	int i, iw, ih, iiw, iih, cw, ch, ix, iy;
//	double ss, tx, ty;
//	ss = 1.0; for ( i = 0; i < ScaleLevel; ++i ) ss /= ScaleFactor;
//
//	iw = (int)(Image_W * ss + 0.5);
//	ih = (int)(Image_H * ss + 0.5);
//
//	iiw = iw - StdObjectBoundingBox_W - ObjectExtent * 2 + 1;
//	iih = ih - StdObjectBoundingBox_H - ObjectExtent * 2 + 1;
//
//	//if (iiw<1 || iih<1) return -1;
//
//	CHiBoostExample tExample;
//	tExample.fIsExamplePos = false;
//	tExample.fIsImagePos = fIsImagePos;
//	tExample.FileIndex = FileIndex;
//
//	tExample.layer_scale_x = tExample.layer_scale_y = ss;
//	//GetStdPartContextScale(tExample.layer_scale_x, tExample.layer_scale_y, NodeIndex);
//	//tExample.layer_scale_x *= ss;
//	//tExample.layer_scale_y *= ss;
//
//	int pe;
//	//pe = PartExtent;
//	pe = 0;
//
//	iw = (int)(Image_W * tExample.layer_scale_x + 0.5);
//	ih = (int)(Image_H * tExample.layer_scale_y + 0.5);
//	GetStdPartContextSize(cw, ch, NodeIndex);
//	iiw = iw - cw - pe * 2 + 1;
//	iih = ih - ch - pe * 2 + 1;
//	if (iiw<1 || iih<1) return -1;
//
//	if (tExample.layer_scale_x>1.0 || tExample.layer_scale_y>1.0)
//	{
//		tx = tExample.layer_scale_x / ScaleFactor;
//		ty = tExample.layer_scale_y / ScaleFactor;
//		if ((tx>1.0 || ty>1.0) && !fAcceptBigImage)
//			return 0;
//	}
//
//	CPointInRectangleRandomSampler ips;
//	ips.Work(iiw, iih, PixelMargin, PixelSampleRate);
//	const int* qspi;
//	for ( qspi = ips.SampledPixelList.pElement, i = 0; i < (int)ips.SampledPixelList.Size; ++i, ++qspi )
//	{
//		ix = (*qspi)%iiw; iy = (*qspi)/iiw;
//		tx = ix + 0.5 + cw * 0.5 + pe;
//		ty = iy + 0.5 + ch * 0.5 + pe;
//		tExample.real_x = tx / tExample.layer_scale_x;
//		tExample.real_y = ty / tExample.layer_scale_y;
//		DstExampleList.PushBack(tExample);
//	}
//
//	return (int)ips.SampledPixelList.Size;
//}
//
//// [*] CDataSet_HiBoost_ByImage
//
//CDataSet_HiBoost_ByImage::CDataSet_HiBoost_ByImage()
//{
//	this->pIPPFE = NULL;
//	_fSharedIPPFE = false;
//}
//
//CDataSet_HiBoost_ByImage::~CDataSet_HiBoost_ByImage()
//{
//	if (!_fSharedIPPFE) CDataStructureTools::MyRelease_Single(this->pIPPFE);
//
//	ExampleAmount = 0;
//	ExampleList.Clear();
//	_LastFileIndex = _LastNode = -1;
//}
//
//void CDataSet_HiBoost_ByImage::InitIPPFE(int NodeIndex, CImagePositionFeatureExtractor* pPrototypeIPFE, int CacheSize)
//{
//	InitIPPFE(NodeIndex, new CImagePyramidPositionFeatureExtractor(pPrototypeIPFE->myClone(), CacheSize), false);
//}
//
//void CDataSet_HiBoost_ByImage::InitIPPFE(int NodeIndex, CImagePyramidPositionFeatureExtractor* pInitializedIPPFE, bool fShared)
//{
//	this->NodeIndex = NodeIndex;
//
//	if (!_fSharedIPPFE) CDataStructureTools::MyRelease_Single(this->pIPPFE);
//
//	this->pIPPFE = pInitializedIPPFE;
//	_fSharedIPPFE = fShared;	
//
//	_LastFileIndex = _LastNode = -1;
//}
//
////void CDataSet_HiBoost_ByImage::InitIPPFE(CImageFilterBank* cpFixedImageFilterBank, int NodeIndex)
////{
////	CDataStructureTools::MyRelease_Single(this->pIPPFE);
////	this->NodeIndex = NodeIndex;
////	
////	this->pIPPFE = new CImagePyramidPositionFeatureExtractor(nsa.GetNodeAppearnceIPFE(NodeIndex)->myClone(), 1);
////	//this->pIPPFE = CFeatureFactory_HiBoost::GenerateIPPFE(cpFixedImageFilterBank, NodeIndex, 1);
////
////	_LastFileIndex = _LastNode = -1;
////}
//
//void CDataSet_HiBoost_ByImage::InitExampleList(
//	string strFN_ExampleList, string strFN_Pfx_ImageCacheHashName,
//	const CSimpleTypeArray<string>* pPosFileNameSet, const CSimpleTypeArray<string>* pNegFileNameSet
//	)
//{
//	char strTemp[10001];
//	sprintf_s(strTemp, "Loading Example List \"%s\" ...", strFN_ExampleList.c_str());
//	CExternalTools::ConsoleTools::ClearCurrentLine();
//	cout<<strTemp;
//
//	this->strFN_Pfx_ImageCacheHashName = strFN_Pfx_ImageCacheHashName;
//	PosFileAmount = (int)pPosFileNameSet->Size;
//	NegFileAmount = (int)pNegFileNameSet->Size;
//	_pPosFileNameSet = pPosFileNameSet;
//	_pNegFileNameSet = pNegFileNameSet;
//	ifstream inFile(strFN_ExampleList.c_str());
//	inFile>>ExampleAmount;
//	ExampleList.Resize(ExampleAmount);
//	int i;
//	for ( i = 0; i < ExampleAmount; ++i ) ExampleList.pElement[i].InputFromStream(inFile);
//	inFile.clear();
//	inFile.close();
//
//	_ImageHandle = 0;
//	_LastFileIndex = _LastNode = -1;
//
//	sprintf_s(strTemp, "Loaded Example List \"%s\" ;", strFN_ExampleList.c_str());
//	CExternalTools::ConsoleTools::ClearCurrentLine();
//	cout<<strTemp<<endl;
//}
//
//void CDataSet_HiBoost_ByImage::InitDrawContextSettings(int W, int H, int Extent)
//{
//	DrawContext_W = W;
//	DrawContext_H = H;
//	DrawContext_Extent = Extent;
//}
//
//void CDataSet_HiBoost_ByImage::SetQuery(int NodeIndex)
//{
//	if (NodeIndex<0 || NodeIndex>=ExampleAmount) return;
//
//	if (pIPPFE!=NULL && this->_ImageHandle!=pIPPFE->ImageHandle)
//	{
//		//cout<<_ImageHandle<<" "<<pIPPFE->ImageHandle<<endl;
//		_ImageHandle = 0;
//		_LastFileIndex = _LastNode = -1;
//	}
//
//	if (NodeIndex == _LastNode) return;
//
//	_LastNode = NodeIndex;
//
//	const CHiBoostExample& tExample = ExampleList.pElement[NodeIndex];
//
//	if (tExample.FileIndex != _LastFileIndex)
//	{
//		_LastFileIndex = tExample.FileIndex;
//
//		CImg<int> imgSrc;
//		char strTemp[10001];
//
//		if (tExample.fIsImagePos)
//		{
//			sprintf_s(strTemp, "%s.Node.%02d.%s.%04d", strFN_Pfx_ImageCacheHashName.c_str(), this->NodeIndex, (tExample.fIsImagePos ? "Pos" : "Neg"), _LastFileIndex);
//			CExternalTools::myLoadImage(_pPosFileNameSet->pElement[_LastFileIndex], imgSrc);
//		}
//		else
//		{
//			sprintf_s(strTemp, "%s.%s.%04d", strFN_Pfx_ImageCacheHashName.c_str(), (tExample.fIsImagePos ? "Pos" : "Neg"), _LastFileIndex);
//			CExternalTools::myLoadImage(_pNegFileNameSet->pElement[_LastFileIndex], imgSrc);
//		}
//
//		if (this->pIPPFE != NULL)
//			_ImageHandle = this->pIPPFE->SetImage(imgSrc, strTemp);
//		else
//			_ImageHandle = 0;
//	}
//
//	CImagePyramidPosition ipp;
//	ipp.InitNew(tExample.real_x, tExample.real_y, tExample.layer_scale_x, tExample.layer_scale_y);
//	if (this->pIPPFE != NULL) this->pIPPFE->SetQuery(ipp);
//}
//
//double CDataSet_HiBoost_ByImage::GetFeature(int FeatureIndex)
//{
//	if (this->pIPPFE==NULL || _LastNode<0 || _LastNode>=ExampleAmount || FeatureIndex<0 || FeatureIndex>=this->pIPPFE->Dim) return 0.0;
//
//	return this->pIPPFE->GetFeature(FeatureIndex);
//}
//
//void CDataSet_HiBoost_ByImage::DrawExample(CImg<int>& imgDst)
//{
//	if (this->pIPPFE==NULL || _LastNode<0 || _LastNode>=ExampleAmount) return;
//
//	CImg<int> imgTemp;
//	
//	C_TRSable_Image trsImage;
//	trsImage.myInit(this->pIPPFE->QueryImageLayer);
//	trsImage.DefaultColor.Resize(3);
//	trsImage.DefaultColor.Fill(128);
//	C_TRSable_Image::CParameters trsConfig;
//	int iw = DrawContext_W + DrawContext_Extent * 2;
//	int ih = DrawContext_H + DrawContext_Extent * 2;
//	trsConfig.myInit(
//		this->pIPPFE->QueryX + 0.5, this->pIPPFE->QueryY + 0.5,
//		iw * 0.5, ih * 0.5, 1.0, 1.0, 0.0, 0.0);
//	trsImage.BuildImage(imgTemp, iw, ih, trsConfig, C_TRSable_Image::EXPANDING_MODE_COLOR);
//	
//	CRectBox<int> bbox;
//	bbox.x = bbox.y = DrawContext_Extent;
//	bbox.w = DrawContext_W;
//	bbox.h = DrawContext_H;
//	CExternalTools::DrawRectBox(imgTemp, bbox, 255, 255, 0);
//
//	const CHiBoostExample& tExample = ExampleList.pElement[_LastNode];
//
//	char strTemp[10001];
//	int jw = iw + 125;
//	int jh = ih;
//	if (jh < 80) jh = 80;
//
//	imgDst.assign(jw, jh, 1, 3);
//	imgDst.fill(255);
//	imgDst.draw_image(imgTemp, 0, 0);
//	sprintf_s(strTemp, "%s Image %04d", (tExample.fIsImagePos ? "Pos" : "Neg"), tExample.FileIndex);
//	CExternalTools::OutputTextToImage(imgDst, strTemp, iw + 5, 5, 255, 255, 255, 255, 0, 0);
//	sprintf_s(strTemp, "Position:");
//	CExternalTools::OutputTextToImage(imgDst, strTemp, iw + 5, 20, 255, 255, 255, 255, 0, 0);
//	sprintf_s(strTemp, "\t<%.2lf, %.2lf>", tExample.real_x, tExample.real_y);
//	CExternalTools::OutputTextToImage(imgDst, strTemp, iw + 5, 35, 255, 255, 255, 255, 0, 0);
//	sprintf_s(strTemp, "Layer Scale:");
//	CExternalTools::OutputTextToImage(imgDst, strTemp, iw + 5, 50, 255, 255, 255, 255, 0, 0);
//	sprintf_s(strTemp, "\t<%.2lf, %.2lf>", tExample.layer_scale_x, tExample.layer_scale_y);
//	CExternalTools::OutputTextToImage(imgDst, strTemp, iw + 5, 65, 255, 255, 255, 255, 0, 0);
//}
//
//int CDataSet_HiBoost_ByImage::GetFeatureDimension()
//{
//	return (this->pIPPFE==NULL ? 0 : this->pIPPFE->GetFeatureDimension());
//}
//
//int CDataSet_HiBoost_ByImage::GetNodeAmount()
//{
//	return ExampleAmount;
//}
//
//int CDataSet_HiBoost_ByImage::GetNodeLabel(int NodeIndex)
//{
//	if (NodeIndex<0 || NodeIndex>=ExampleAmount) return -1;
//	return (ExampleList.pElement[NodeIndex].fIsExamplePos ? +1 : -1);
//}
//
//double CDataSet_HiBoost_ByImage::GetNodeInitialWeight(int NodeIndex)
//{
//	return 1.0;
//}
//
//double CDataSet_HiBoost_ByImage::GetNodeFeature(int NodeIndex, int FeatureIndex)
//{
//	if (NodeIndex<0 || NodeIndex>=ExampleAmount) return 0.0;
//	SetQuery(NodeIndex);
//
//	//return 0.0;
//
//	return GetFeature(FeatureIndex);
//}
//
//size_t CDataSet_HiBoost_ByImage::GetMemoryUsage() const
//{
//	return sizeof(int) * 5
//		+ sizeof(CImagePyramidPositionFeatureExtractor*)
//		+ sizeof(const CSimpleTypeArray<string>*) * 2
//		+ ExampleList.GetMemoryUsage()
//		+ this->pIPPFE->GetMemoryUsage();
//}

// [*] CHiBoostGroundTruthList

bool CHiBoostGroundTruthList::GetGroundTruth(CHiBoostGroundTruth& DstGroundTruth, CImg<int>& DstSourceImage, int GroundTruthIndex, double MinimalAcceptableImageLayerScale) const
{
	if (GroundTruthIndex<0 || GroundTruthIndex>=Amount_GroundTruth) return false;

	DstGroundTruth = GroundTruthList.pElement[GroundTruthIndex];

	if (DstGroundTruth.MaterialIndex<0 || DstGroundTruth.MaterialIndex>=Amount_SrcImage_Pos) return false;

	CImg<int> imgSrc;
	CExternalTools::myLoadImage(List_strFN_SrcImage_Pos.pElement[DstGroundTruth.MaterialIndex], imgSrc);

	int iw_org = imgSrc.width;
	int ih_org = imgSrc.height;
	if (DstGroundTruth.fIsFlipped)
	{
		int ix, iy, iv, tt;
		int* qid;
		for ( iv = 0; iv < (int)imgSrc.dim; ++iv ) for ( iy = 0; iy < ih_org; ++iy )
		{
			qid = imgSrc.data + iw_org * (ih_org * iv + iy);
			for ( ix = 0; ix+ix+1 < iw_org; ++ix )
			{
				tt = qid[ix];
				qid[ix] = qid[iw_org-1-ix];
				qid[iw_org-1-ix] = tt;
			}
		}
	}

	double BaseImageLayerScale;
	BaseImageLayerScale = pExampleSettings->ComputeGeneralIplScale(&DstGroundTruth);
	//pHiBoostExampleConfig->ComputeParsedObject_ImageLayerScale(BaseImageLayerScale, &DstGroundTruth);

	CRectBox<double> oBox, sBox, rBox;

	pExampleSettings->LargeBicExampleConfig.MakeContextBoxFromCenterAndIplScale(oBox, DstGroundTruth.Center_X, DstGroundTruth.Center_Y, BaseImageLayerScale);
	//pHiBoostExampleConfig->pHiBoostNodeContextConfig->GetContextBoxForNodeInstance(oBox, DstGroundTruth.Center_X, DstGroundTruth.Center_Y, 1.0/BaseImageLayerScale)	;
	////pHiBoostExampleConfig->pHiBoostNodeContextConfig->GetRealBoxForNodeInstance(oBox, &DstGroundTruth);

	oBox.w += oBox.x; oBox.h += oBox.y;
	//oBox.x = (oBox.x < 0 ? 0 : oBox.x);
	//oBox.y = (oBox.y < 0 ? 0 : oBox.y);
	//oBox.w = (oBox.w > iw_org ? iw_org : oBox.w);
	//oBox.h = (oBox.h > ih_org ? ih_org : oBox.h);
	oBox.w -= oBox.x; oBox.h -= oBox.y;

	CZoomConfig ZoomConfig;
	sBox = oBox;
	if (MinimalAcceptableImageLayerScale>EPS && BaseImageLayerScale<MinimalAcceptableImageLayerScale)
	{
		BaseImageLayerScale /= MinimalAcceptableImageLayerScale;
		ZoomConfig.myInit(BaseImageLayerScale, BaseImageLayerScale, sBox.x, sBox.y, 0.0, 0.0);
	}
	else
		ZoomConfig.myInit(1.0, 1.0, sBox.x, sBox.y, 0.0, 0.0);
	ZoomConfig.WorkOnBox(rBox, sBox);
	DstGroundTruth.DoTransformation(&ZoomConfig);
	CZoomableImage ZoomImage;
	ZoomImage.myInit(imgSrc);
	ZoomImage.BuildImage(
		DstSourceImage,
		CMyMath::TranslateNumber_Round(rBox.w, (int)0),
		CMyMath::TranslateNumber_Round(rBox.h, (int)0),
		ZoomConfig, CDenseImage::EXPANDING_MODE_EDGE);

	//CImageTransformation tfmConfig;
	//tfmConfig.Clear();
	//sBox = oBox;
	//if (MinimalAcceptableImageLayerScale>EPS && BaseImageLayerScale<MinimalAcceptableImageLayerScale)
	//{
	//	BaseImageLayerScale /= MinimalAcceptableImageLayerScale;
	//	tfmConfig.PushBack(new C_ImgTran_Scale(sBox.x+sBox.w*0.5, sBox.y+sBox.h*0.5, BaseImageLayerScale));
	//	tfmConfig.Work(sBox, sBox);
	//}

	//tfmConfig.PushBack(new C_ImgTran_Translate(sBox.x, sBox.y, 0.0, 0.0));
	//tfmConfig.Work(rBox, oBox);

	//DstGroundTruth.DoTransformation(tfmConfig);

	//CTransformableImage trsImage;
	//trsImage.myInit(imgSrc);
	//trsImage.BuildImage(
	//	DstSourceImage,
	//	CMyMath::TranslateNumber_Round(rBox.w, (int)0),
	//	CMyMath::TranslateNumber_Round(rBox.h, (int)0),
	//	tfmConfig, CDenseImage::EXPANDING_MODE_EDGE);

	//DstSourceImage.display();

	return true;
}

